package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.xml.ws.FaultAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/dish")
public class DishController {
    @Autowired
    private DishService dishService;
    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    //添加操作
//   @PostMapping
//    public R<String> save(@RequestBody DishDto dishDto){
//       dishService.saveWithFlavor(dishDto);
//       return R.success("新增菜品成功！！！");
//   }

//    添加操作
    @PostMapping
    @Transactional
    public R<String> save(@RequestBody DishDto dishDto){
//        新增菜品，同时保存对应的口味数据
        boolean flag = dishService.save(dishDto);
        //同步redis中的菜品列表数据:删除缓存中存储的列表数据
        redisTemplate.delete("dish_"+dishDto.getCategoryId());

        //获取新增菜品的id
        Long dishId = dishDto.getId();
        //获取菜品的口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        if(flavors.size()>0){
            for (DishFlavor flavor : flavors) {
                //dishflavor口味的dishid与dish的id一致
                flavor.setDishId(dishId);
            }
        }
        if(flag){
            //保存菜品口味数据到菜品口味表dish_flavor
            dishFlavorService.saveBatch(flavors);
            return R.success("新增菜品成功！！");
        }
          return R.error("新增失败！！");
    }

//分页+模糊查询操作
        @GetMapping("/page")
  public R<Page> page(Integer page,Integer pageSize,String name){
        Page<Dish> dishPage = new Page<>(page,pageSize);
            //分页查询dishdto类型
         Page<DishDto> dishDtoPage = new Page<>();
        //获取菜品的查询
        LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.like(StringUtils.isNotEmpty(name),Dish::getName,name);

       //执行菜品分类部分查询
        dishService.page(dishPage,lambdaQueryWrapper);
        //对象拷贝
//         BeanUtils.copyProperties(dishPage,dishDtoPage,"records");
        //菜品分类category查询的id等于dish的category_id
        //获取菜品分页查询的集合每一条记录
        List<Dish> records = dishPage.getRecords();

        //新建一个集合来接收菜品分类名称
        List<DishDto> dishDtos = new ArrayList<>();
            for (Dish record : records) {
                DishDto dishDto = new DishDto();
//            record.getCategoryId()拿到的是dish的CategoryId数据
            Long categoryId = record.getCategoryId();
            //通过categoryId来获取Category对象
            Category category = categoryService.getById(categoryId);
           if(category!=null){
               //菜品名称
               String name1 = category.getName();
               dishDto.setCategoryName(name1);
               BeanUtils.copyProperties(record,dishDto);
               dishDtos.add(dishDto);
//               dishDtoPage.setRecords(dishDtos);
           }
            }
//            dishDtos.forEach(System.out::println);

            dishDtoPage.setRecords(dishDtos);

            dishDtoPage.setTotal(dishPage.getTotal());
        return R.success(dishDtoPage);
        }
    //分页+模糊查询操作第二种方法 .stream.map().collect(Collectors.toList());
/*  @GetMapping("/page")
  public R<Page> page(Integer page,Integer pageSize,String name){
      Page<Dish> dishPage = new Page<>();
      Page<DishDto> dishDtoPage = new Page<>();
      LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
      wrapper.like(StringUtils.isNotEmpty(name),Dish::getName,name);
      dishService.page(dishPage,wrapper);
      BeanUtils.copyProperties(dishPage,dishDtoPage,"records");
      List<Dish> records = dishPage.getRecords();
      List<DishDto> list = records.stream().map((dishitem -> {
          Long categoryId = dishitem.getCategoryId();
          Category category = categoryService.getById(categoryId);
          String categoryName = category.getName();
          DishDto dishDto = new DishDto();
          dishDto.setCategoryName(categoryName);
          BeanUtils.copyProperties(dishitem, dishDto);
          return dishDto;
      })).collect(Collectors.toList());
      dishDtoPage.setRecords(list);
      dishDtoPage.setTotal(dishPage.getTotal());
      return R.success(dishDtoPage);
  }*/



//    根据id查询菜品数据，用于回显
    @GetMapping("/{id}")
    public R<DishDto> updateById(@PathVariable Long id){
        //查询菜品基本信息，从dish表查询
        Dish dish = dishService.getById(id);
        DishDto dishDto = new DishDto();
        //把dish菜品数据 赋值/拷贝 给 dishDto对象
        BeanUtils.copyProperties(dish,dishDto);
        //查询当前菜品对应的口味信息,从dishflavor查询
        LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //找出dishflavor中的dishid与dish中的id相等的情况
        lambdaQueryWrapper.eq(DishFlavor::getDishId,dish.getId());
        //查找所有dishflavor口味的情况
        List<DishFlavor> list = dishFlavorService.list(lambdaQueryWrapper);
        //将口味情况显示到dishdto中
        dishDto.setFlavors(list);
        return R.success(dishDto);
    }
//   修改菜品
    @PutMapping
    @Transactional
    public R<String> update(@RequestBody DishDto dishDto){
          //修改菜品的信息(除菜品口味)
          dishService.updateById(dishDto);

          //清理所有菜品的缓存数据
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        //取出修改菜品的id
        Long id = dishDto.getId();
//        (以下是如果要更改口味数据的情况下)
         //删除原有的口味dishflavors数据
        LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DishFlavor::getDishId,id);
        dishFlavorService.remove(lambdaQueryWrapper);
        //添加菜品口味数据
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(id);
        }
//        插入数据时，要插入数据的主键数据 (…)已经存在，不能再重复添加了,所以用修改
        dishFlavorService.saveBatch(flavors);
//        dishFlavorService.updateBatchById(flavors);
        return R.success("修改成功！！");
    }

//        @PutMapping
//    public R<String> update(@RequestBody DishDto dishDto){
//          //修改菜品的信息(除菜品口味)
//          dishService.updateById(dishDto);
//          //取出修改菜品的id
//        Long id = dishDto.getId();
////        (以下是如果要更改口味数据的情况下)
//         //删除原有的口味dishflavors数据
//        LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(DishFlavor::getDishId,id);
//        dishFlavorService.update(lambdaQueryWrapper);
//        return R.success("修改成功！！");
//    }

    //删除与逻辑删除
     @DeleteMapping
     @Transactional
     public R<String> deleteDish(@RequestParam List<Long> ids){
        //删除菜品的id 让is_deleted从0变为1
         dishService.removeByIds(ids);
        //删除菜品口味的dish_id  让is_deleted从0变为1
         LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         for (Long id : ids) {
             lambdaQueryWrapper.eq(DishFlavor::getDishId,id);
             dishFlavorService.remove(lambdaQueryWrapper);
         }
         return R.success("删除成功！！！");
     }


    //单个起售和单个停售
//    @PostMapping("/status/{status}")
//    public R<String> status(Dish dish) {
//        //修改菜品的售卖状态 1:启售 0:停售
//        LambdaUpdateWrapper<Dish> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//        lambdaUpdateWrapper.set(Dish::getStatus,dish.getStatus());
//        dishService.update(lambdaUpdateWrapper);
//        return R.success("修改菜品售卖状态成功！！！");
//    }
//
//        起售/停售 批量起售/批量停售
//    @PostMapping("/status/{status}")
//    public R<String> status(@RequestParam List<Long> ids, Dish dish) {
//        //修改菜品的售卖状态 1:启售 0:停售
////          update dish set status = ? where id in (1,2,3)
//        //构造修改条件构造器
//        LambdaUpdateWrapper<Dish> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//        //设置单个或者是多个id的状态 set status = ？
//        lambdaUpdateWrapper.set(Dish::getStatus,dish.getStatus());
//        // where id in (1,2,3) id包含单个或者是多个
//        lambdaUpdateWrapper.in(Dish::getId,ids);
//        dishService.update(lambdaUpdateWrapper);
//        return R.success("修改菜品售卖状态成功！！！");
//    }
     //dish.getStatus()==@PathVariable Integer status
//     起售/停售 批量起售/批量停售第二种方法
    @PostMapping("/status/{status}")
    public R<String> status(Dish dish,@RequestParam List<Long> ids){
        //获取修改操作Dish对象的集合
        List<Dish> dishes = dishService.listByIds(ids);
        for (Dish dish1 : dishes) {
            //设置每一个状态的属性
            dish1.setStatus(dish.getStatus());
        }
//        //更新集合的操作
        dishService.updateBatchById(dishes);
        return R.success("修改菜品售卖状态成功！！！");
    }

//    根据分类id查询该分类下的所有菜品集合
//    @GetMapping ("/list")
//    public R<List> list(Dish dish){
//        //通过查询dish菜单中dish数据中categoryid是否有相等来进行分类
//        LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//       //先找出菜品的各种种类具体菜的名称，在判断菜的状态
//        lambdaQueryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
//        //判断菜品的状态是否状态为1 为起售的状态
//        lambdaQueryWrapper.eq(Dish::getStatus,1);
//
//        List<Dish> list = dishService.list(lambdaQueryWrapper);
//
//        return R.success(list);
//    }

        @GetMapping ("/list")
    public R<List<DishDto>> list(Dish dish){
        //在list方法中,查询数据库之前,先查询缓存, 缓存中有数据, 直接返回**
            List<DishDto> dishDtoList=null;
            //动态构造key
            String key="dish_"+dish.getCategoryId();//dish_1397844391040167938_1
           //先从redis获取数据
            dishDtoList= (List<DishDto>) redisTemplate.opsForValue().get(key);
          //如果存在,直接返回,无须查询数据
            if(dishDtoList!=null){

                //如果redis存在,直接返回,无需查询数据

                return R.success(dishDtoList);
            }
            //返回既要有dish数据也要有dishfalvor数据 将dish数据拷贝到dishdto数据中
            LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
            wrapper.eq(Dish::getStatus,1);
            List<Dish> list = dishService.list(wrapper);
            ArrayList<DishDto> dishDtoss = new ArrayList<>();
            for (Dish dish1 : list) {
                DishDto dishDto = new DishDto();
//                将dish数据拷贝到dishdto数据中
                BeanUtils.copyProperties(dish1,dishDto);
                //将每一种dish对应口味在dishflavor中dishid找出
                LambdaQueryWrapper<DishFlavor> wrapper1 = new LambdaQueryWrapper<>();
                //找出每一个菜品与菜品口味对应的id数据
                wrapper1.eq(DishFlavor::getDishId,dish1.getId());
                List<DishFlavor> dishFlavors = dishFlavorService.list(wrapper1);
                //将口味放到dishdto中
                dishDto.setFlavors(dishFlavors);
                dishDtoss.add(dishDto);
            }
            //如果不存在,需要查询数据库,将查询到的菜品放到redis
            //将持久层查询的菜品列表数据,存储到redis。让key保持一致
            redisTemplate.opsForValue().set(key,dishDtoss);
           return R.success(dishDtoss);
        }



















}
